/**
 * \file Master.h
 *
 * ICC Driver
 * Written 2011, by Anthony Berlin and Alexander Carlqvist
 *
 * This file is part of ICC.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MASTER_H
#define MASTER_H

#include "SourceFile.h"

#include <Exception/Exception.h>
#include <GCB/Object.h>
#include <GCB/Common.h>

class Master : public Object
{
public:
    /// The heart of the program flow.
    void run(int& argc, char** argv);

    /// Return the filename of this application.
    string& get_app_filename();

    /// Parameters.
    string p_output;
    bool p_help;
    bool p_version;
    bool p_verbose;

private:
    /// Some application information.
    string APP_NAME;
    string APP_ABBR;
    string APP_VERSION;
    string APP_AUTHOR;
    string APP_YEAR;
    string APP_TITLE;
    string APP_FILENAME;

    /// Initalize the application.
    void init_app(const char* title);

    /// [Windows]: Set the application title.
    #ifdef WIN32
        void set_app_title(string& title) const;
    #endif

    /// Execute a program to process a \c SourceFile with.
    bool exec(string program, SourceFile* src);

    /// Print the help message.
    void print_help() const;

    /// Print the application version.
    void print_version() const;

    /// Print the usage message.
    void usage() const;

    /// Parse the parameters passed to the application, and configure it.
    void parse_params(int& argc, char** argv);

    /// Add a parameter error about in the form of "Unrecognized option 'option'.".
    void unrecognized_option(int& arg, char** argv);

    /// Add a parameter error about in the form of "Argument to 'option' is missing.".
    void missing_arg(int& arg, char** argv);

    /// Add a parameter error to 'm_paramErrorList'.
    void push_param_error(string& errMsg);
    void push_param_error(const char* errMsg);

    /// Output a string to the screan if the option '-quiet' is not used.
    template <class T>
    void output(T msg) const;

    /// Write something to the console. It makes sure the string never includes a line that is longer
    /// than 79 characters. If it does, an exception is thrown. It always ends with a new-line.
    void write_console(const char* msg) const;
    void write_console(string& msg) const;

    /// Launch another process.
    int launch(string path, list<string>& args);

    /// Source files to compile.
    list<SourceFile*> m_sourceFiles;

    /// List of parameter errors.
    list<string> m_paramErrorList;
};

#define sMaster Singleton<Master>::instance()

#endif // MASTER_H
